#ifndef Rules_h
#define Rules_h

#include "RuleLength.h"
#include "RuleByKey.h"
#include "RuleTokens.h"
#include "RuleFlag.h"
#include "Log.h"


class Rules_T
{
public:
	char szName[MAX_PATH];

	RuleTokens_T verbRule;
	RuleTokens_T httpVersionRule;
	RuleTokens_T extensionRule;
	RuleTokens_T hostPortRule;
	RuleTokens_T headerNameRule;
	RuleTokens_T urlSequenceRule;
	RuleTokens_T querySequenceRule;

	RuleByKey_T maxLenByHeaderRule;

	RuleFlag_T allowDotInUrlRule;
	RuleFlag_T allowHighBitInUrlRule;
	RuleFlag_T allowHighBitInQueryRule;
	RuleFlag_T allowHighBitInPayloadRule;
	RuleFlag_T canonUrlBeforeScanRule;
	RuleFlag_T canonQueryBeforeScanRule;
	RuleFlag_T failOnReCanonUrlChangeRule;
	RuleFlag_T failOnReCanonQueryChangeRule;
	
	RuleLength_T urlMaxLenRule;
	RuleLength_T queryMaxLenRule;
	RuleLength_T headerNameMaxLenRule;
	RuleLength_T headerValueMaxLenRule;
	RuleLength_T payloadMaxLenRule;
	RuleLength_T contentLengthMaxLenRule;
	
	Buffer_T rejectPageContent;
	char szRejectFilename[MAX_PATH];

	// RemoveBanner, ChangeBanner Key
	RuleFlag_T removeBannerRule;
	String_T serverBanner;

	// LogFilesDir Key
	char szLogFilesDir[MAX_PATH];
	Log_T * logPtr;

private:
	char _szConfigFile[MAX_PATH];

public:
	Rules_T(const char * szDefaultLogFilesDir, const char * szConfigFile);
	~Rules_T();

public:
	void Log(const Session_T & session, Request_T & request, const Error_T & err);

	Error_T::Code_T FilterHeaders(Request_T & request);
	Error_T::Code_T FilterEntitySize(unsigned int entitySize);
	Error_T::Code_T FilterEntityData(const Buffer_T & entityData);

private:
	void CrackUrl(const Buffer_T & url, Buffer_T & urlPath, Buffer_T & urlFile, Buffer_T & urlExt);
	Error_T::Code_T FilterVerb(const Buffer_T & verb);
	Error_T::Code_T FilterSchema(const Buffer_T & schema);
	Error_T::Code_T FilterUrl(Buffer_T & url);
	Error_T::Code_T FilterQuery(Buffer_T & query);
	Error_T::Code_T FilterVersion(const Buffer_T & version);
	Error_T::Code_T FilterHeaderName(const Buffer_T & headerName);
	Error_T::Code_T FilterHeaderValue(const Buffer_T & headerName, const Buffer_T & headerValue);

public:
	static List_T<Rules_T> * s_rulesListPtr;
	static void Load();
	static void Unload();
	static Rules_T * Load(const char * szDefaultLogFilesDir, const char * szConfigFile);
};

#endif //Rules_h